#include "cCUIWindow.h"
#include <string.h>

sCUIRGB CUIRGB(float r, float g, float b)
{
	sCUIRGB color = {r, g, b};
	return color;
}

cCUIWindow::cCUIWindow(cCUIWindow *parent, const char *title, int width, int height)
{
	if(!glfwInit())
	{
		printf("cCUIWindow::cCUIWindow - Error initialising glfw!\n");
		glfwTerminate();
	}
	memset(&windowDetails, 0, sizeof(windowDetails));
	strcpy(&windowDetails.title[0], title);
	windowDetails.visible = false;
	windowDetails.width = width;
	windowDetails.height = height;
	windowDetails.parentWindow = parent;
	windowDetails.windowHandle = glfwCreateWindow(windowDetails.width, windowDetails.height, windowDetails.title, NULL, NULL);
	firstrun = true;
	bgImage = false;
	brush = new cCUIBrush();
	backgroundColor = CUIRGB(0.0f, 0.0f, 0.0f);
}

cCUIWindow::~cCUIWindow()
{
}

void cCUIWindow::setBackground(cCUIImage* background)
{
	bgImage = true;
	backgroundImage = background;
	printf("cCUIWindow: Got a background image, switching to GL_TEXTURE_2D\n");
}

void cCUIWindow::show(bool showSetting)
{
}

GLFWwindow* cCUIWindow::getWindow()
{
	return windowDetails.windowHandle;
}

void cCUIWindow::pollEvents()
{
	glfwPollEvents();
}

void cCUIWindow::addChild(cCUIWindow *child)
{
	windowDetails.children.push_back(child);
}

void cCUIWindow::addWidget(cCUIWidget *widget)
{
	windowDetails.widgets.push_back(widget);
}

void cCUIWindow::addCallBack(CUICallBack callback, int id)
{
	callbacks[id] = callback;
}

void cCUIWindow::update()
{
	//Is this the first time we've run the update() function?
	if(firstrun)
	{
		sCUIEvent e;
		callbacks[CUI_OnLoad](e); //Call onload callback. This allows the user to initialise everything.
		firstrun = false;
	}
	paint();
	drawWidgets();
}

//Paints the window. Also handles resizing.
void cCUIWindow::paint()
{
		float ratio;
		glfwGetFramebufferSize(windowDetails.windowHandle, &windowDetails.width, &windowDetails.height);
        ratio = (float)windowDetails.width / (float)windowDetails.height;
        glViewport(0, 0, windowDetails.width, windowDetails.height);
		glClear(GL_COLOR_BUFFER_BIT);
		glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f);

        glMatrixMode(GL_MODELVIEW);
		
		if(!bgImage)
		{
			glBegin(GL_QUADS);
			//This quad will always resize to fill the full window. It's the base of the window.
			//This is exclusively for windows with no texture.
			glColor3f(backgroundColor.r, backgroundColor.g, backgroundColor.b);
			glVertex3f(-1.0f*ratio, -1.0f, 0.0f);
			glVertex3f(-1.0f*ratio, 1.0f, 0.0f);
			glVertex3f(1.0f*ratio, 1.0f, 0.0f);
			glVertex3f(1.0f*ratio, -1.0f, 0.0f);
		}
		else
		{
			//We have a background image,  draw it instead
			glEnable(GL_TEXTURE_2D);
			glBindTexture(GL_TEXTURE_2D, backgroundImage->GLid);

			glBegin (GL_QUADS);
			glColor3f(1.0f,1.0f,1.0f); //This stops widgets from interfering with the window.
			glTexCoord2f (0.0, 1.0);
			glVertex3f(-1.0f*ratio, -1.0f, 0.0f);
			glTexCoord2f (0.0, 0.0);
			glVertex3f(-1.0f*ratio, 1.0f, 0.0f);
			glTexCoord2f (1.0, 0.0);
			glVertex3f(1.0f*ratio, 1.0f, 0.0f);
			glTexCoord2f (1.0, 1.0);
			glVertex3f(1.0f*ratio, -1.0f, 0.0f);
		}

        glEnd();
		glDisable(GL_TEXTURE_2D); //Stop widgets from interfering with the window.

}

void cCUIWindow::drawWidgets()
{
	if(windowDetails.widgets.size() > 0) //If so, we have widgets to draw.
	{
		//i is unsigned int to keep the compiler happy about signed/unsigned mismatches.
		for(unsigned int i = 0; i<windowDetails.widgets.size(); i++)
		{
			windowDetails.widgets.at(i)->paint(brush); //Ask the current widget to draw itself.
		}
	}
}